/*
 * @Descripttion: 快捷键注册
 * @Author: 人生只如初见
 * @Date: 2021-09-23 17:01:37
 * @LastEditors: 人生只如初见
 * @LastEditTime: 2021-09-27 11:41:24
 */
import { KeyboardCode } from './keybord-code'
class Command {
  constructor(editor) {
    this.state = { // 前进后退需要指针
      current: -1, // 前进后退的索引值
      queue: [], //  存放所有的操作命令
      destroyArray: [],  // 所有需要被销毁的命令集合
      commandArray: [] // 存放所有的命令
    }
    this.editor = editor
    this.commands = {}; // 制作命令和执行功能一个映射表  undo : ()=>{}  redo:()=>{}
    // 监听键盘事件
    let init = this.keyboardEvent()
    this.state.destroyArray.push(init())
  }
  execute = (cmd) => {
    // 执行命令
    cmd.redo()
    // 如果该命令不允许撤销/重做，结束～
    if (!cmd.inMemory) {
      return
    }
    let { queue, current } = this.state;
    // 如果先做了 操作1 -> 操作2 => 操作3 => 撤销： 操作4 => 操作3
    // 操作1 -> 操作3
    if (queue.length > 0) {
      queue = queue.slice(0, current + 1); // 可能在操作的过程中有撤销操作，所以根据当前最新的current值来计算新的队列
      this.state.queue = queue;
    }
    queue.push(cmd); // 保存指令的前进后退
    this.state.current = current + 1;
  }
  /** 注册 */
  registry = (command) => {
    this.state.commandArray.push(command)
    this[command.name] = command.execute
  }
  /** 销毁指定命令 */
  dispose = (name) => {
    let index = this.state.commandArray.findIndex(command => command.name === name)
    this.state.commandArray.splice(index, 1)
    delete this[name]
  }
  keyboardEvent = () => {
    const onKeydown = (event) => {
      const { keyCode, shiftKey, altKey, ctrlKey, metaKey } = event
      let keyString = []
      if (ctrlKey || metaKey) keyString.push('ctrl')
      if (shiftKey) keyString.push('shift')
      if (altKey) keyString.push('alt')

      keyString.push(KeyboardCode[keyCode])
      const keyNames = keyString.join('+')
      console.log('keyNames', keyNames);

      let commandArray = this.state.commandArray
      // 执行对应键盘命令
      commandArray.forEach(({ keyboard, execute }) => {
        if (!keyboard) {
          return
        }
        const keys = Array.isArray(keyboard) ? keyboard : [keyboard]
        if (keys.indexOf(keyNames) > -1) {
          execute()
          event.stopPropagation()
          event.preventDefault()
        }
      })
    }
    const init = () => { // 初始化事件
      window.addEventListener('keydown', onKeydown)
      return () => { // 销毁事件
        window.removeEventListener('keydown', onKeydown)
      }
    }
    return init
  }
}



let useCommand = new Command()

// 注册命令
useCommand.registry({
  name: 'redo', // 重做
  keyboard: ['ctrl+y', 'ctrl+shift+z'],
  execute(){
    let _self = useCommand
    let item = _self.state.queue[_self.state.current + 1]; // 找到当前的下一步还原操作
    if (item) {
      item.redo && item.redo();
      _self.state.current++;
    }
  }
})
useCommand.registry({
  name: 'undo', // 撤销
  keyboard: ['ctrl+z'],
  execute(){
    let _self = useCommand
    if (_self.state.current == -1) return; // 没有可以撤销的了
    let item = _self.state.queue[_self.state.current]; // 找到上一步还原
    if (item) {
      item.undo && item.undo(); // 这里没有操作队列
      _self.state.current--;
    }
  }
})


export default useCommand